package com.syjy.tunnelworker.senders.iml;


import com.syjy.DataExchangeException;
import com.syjy.container.ProtocolDataContainer;
import com.syjy.tunnelinfo.DataPoint;
import com.syjy.tunnelinfo.TunnelStatus;
import com.syjy.tunnelinfo.sendertunnelinfo.SenderCdtRtuTunnelInfo;
import com.syjy.tunnelworker.BaseProtocolTunnel;
import com.syjy.tunnelworker.senders.DataSenderInterface;
import com.syjy.tunnelworker.workassist.SingleThreadPoolExecutorUtil;
import com.syjy.tunnelworker.workassist.cdt.MyCDTDataTransmitter;
import wei.yigulu.cdt.netty.CDTSlaver;
import wei.yigulu.modbus.domain.datatype.ModbusDataTypeEnum;
import wei.yigulu.purejavacomm.PureJavaCommChannelConfig;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

/**
 * cdt Rtu 采集通道
 * 转发点表 默认点表连续
 *
 * @author: xiuwei
 * @version:
 */
public class CdtRtuDataSender extends BaseProtocolTunnel<SenderCdtRtuTunnelInfo,CDTSlaver> implements DataSenderInterface {



	/**
	 * 自定义的CDT slave 的数据发送逻辑   CDTDataTransmitter的实现类
	 */
	MyCDTDataTransmitter myCDTDataTransmitter = new MyCDTDataTransmitter(this);


	/**
	 * 顶层的构造方法
	 *
	 * @param tunnelInfo cdt转发的通道信息
	 */
	public CdtRtuDataSender(SenderCdtRtuTunnelInfo tunnelInfo) {
		super(tunnelInfo);
	}

	@Override
	public BaseProtocolTunnel startTunnel() throws DataExchangeException {
		log.info("Cdt Rtu slaver {}  开始监听", getTunnelInfo().getTunnelName());
		protocolTunnelContainer.addUpdateDateTask(this);
		if (this.protocolBuilder != null && !TunnelStatus.BUILT.equals(this.getTunnelStatus())) {
			protocolBuilder.stop();
			buildTunnel();
		}
		try {
			SingleThreadPoolExecutorUtil.executeBySingleThreadExecutor(() -> {
				protocolBuilder.create();
				log.warn("cdt slaver {} 串口监听失败", getTunnelInfo().getTunnelName());
				this.setTunnelStatus(TunnelStatus.LISTENSERIALFAIL);
			});
		} catch (Exception e) {
			log.warn("cdt slaver {} 串口监听异常", getTunnelInfo().getTunnelName());
			this.setTunnelStatus(TunnelStatus.LISTENSERIALFAIL);
			throw new DataExchangeException(10013, "cdt rtu slave通道创建时发生异常");
		}
		if (!TunnelStatus.LISTENSERIALFAIL.equals(getTunnelStatus())) {
			setTunnelStatus(TunnelStatus.LISTENSERIALSUCCESS);
		}
		return this;
	}

	@Override
	public BaseProtocolTunnel buildTunnel() throws DataExchangeException {
		parseGatherDataPoint();
		protocolBuilder = new CDTSlaver(getTunnelInfo().getSerialName(), myCDTDataTransmitter.setLog(log));
		protocolBuilder.setLog(log);
		protocolBuilder.setBaudRate(getTunnelInfo().getBaudRate()).setDataBits(PureJavaCommChannelConfig.Databits.valueOf(8)).setParity(PureJavaCommChannelConfig.Paritybit.valueOf(this.getTunnelInfo().getParity()));
		this.setTunnelStatus(TunnelStatus.BUILT);
		getProtocolTunnelContainer().addTunnel(this);
		log.info("成功创建CdtRtuSlaver通道对象：{}", this.tunnelInfo.getTunnelName());
		return this;
	}

	@Override
	public BaseProtocolTunnel tunnelStop() throws DataExchangeException {
		if (this.protocolBuilder != null) {
			this.protocolBuilder.stop();
		}
		log.info("关闭CdtRtuSlaver通道：{}", this.tunnelInfo.getTunnelName());
		return super.tunnelStop();
	}

	@Override
	public void parseGatherDataPoint() throws DataExchangeException {

	}


	@Override
	public void updateData2Protocol() {
		ProtocolDataContainer protocolDataContainer = ProtocolDataContainer.getInstance();
		Map<Integer, Boolean> yxVal = new HashMap<>();
		Map<Integer, Integer> ycVal = new HashMap<>();
		for (DataPoint d : this.getTunnelInfo().getDataPoints()) {
			if (ModbusDataTypeEnum.A16.equals(d.getDataType())) {
				yxVal.put(d.getProtocolPoint(), protocolDataContainer.getBoolean(d.getId()));
			} else {
				ycVal.put(d.getProtocolPoint(), protocolDataContainer.getNumber(d.getId()).multiply(BigDecimal.valueOf(d.getMag())).intValue());
			}
		}
		myCDTDataTransmitter.setImportantYc(ycVal);
		myCDTDataTransmitter.setYx(yxVal);
	}


}
